#include "lib.h"

#include "bratgame.h"
#include "bratconn.h"
#include "shue.h"
#include "brathand.h"
#include "cardmgr.h"

static CardMgr stdMgr;

#define NO_DRAW		10		// column in sBankHit representing no player draw

static int32 sBankHit[10][11] =
{
//Bank	  0  1  2  3  4  5  6  7  8  9  N		(----- Player's draw card
/* 0 */	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
/* 1 */	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
/* 2 */	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
/* 3 */	{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 },
/* 4 */	{ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1 },
/* 5 */	{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1 },
/* 6 */	{ 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
/* 7 */	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* 8 */	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* 9 */	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

bool8
BratGame::deal(BratConnection* conn, int32* bets, int32 balance)
{
	BratHand bank(&stdMgr), player(&stdMgr);
	int32 payout[NUMBETS];
	Shue *shue;
	bool8 result = false;

	ShueGameInfo sgi;
	sgi.gameId = GAMEID;
	sgi.machId = MACHID;
    #ifdef FORCEDSHOE 
       sgi.pid=conn->GetPID();
    #endif



	shue = new Shue(&stdMgr, 6, sgi);

	if (shue)
	{
		int32 playerDraw, pscore, bscore;
		int32 outcome, balAdjust, commission;

		shue->shuffle();

		player.add(shue->getCard());
		bank.add(shue->getCard());
		player.add(shue->getCard());
		bank.add(shue->getCard());

		if (!player.natural() && !bank.natural())
		{
			if (player.score() <= 5)
			{
				player.add(shue->getCard()); 

				playerDraw = player.cardScore(player.getLastCard());
			}
			else
				playerDraw = NO_DRAW;

			if (sBankHit[bank.score()][playerDraw])
				bank.add(shue->getCard());
		}

		balAdjust = 0;		// initial bets already subtracted from balance
		pscore = player.score();
		bscore = bank.score();

		if (pscore < bscore)
			outcome = BANKER;
		else if (pscore > bscore)
			outcome = PLAYER;
		else
			outcome = TIE;

		balAdjust += calcPayouts(outcome, bets, payout, &commission, conn->getTiePayoutOdds());

		if (conn->trackGame(&bank, &player, bets, payout, NUMBETS, commission,
			outcome, balAdjust, &balance))
		{
			conn->msgStart();
			conn->msgAdd((uint8)'D');
			conn->msgAdd((uint8)(bank.getCount() & 0xff));
			conn->msgReleaseBuf(bank.out(conn->msgGetBuf()));
			conn->msgAdd((uint8)(player.getCount() & 0xff));
			conn->msgReleaseBuf(player.out(conn->msgGetBuf()));
			conn->msgAdd(payout[BANKER]);
			conn->msgAdd(payout[PLAYER]);
			conn->msgAdd(payout[TIE]);
			conn->msgAdd(commission);
			conn->msgAdd((uint8)(outcome & 0xff));
			conn->msgAdd(balAdjust - bets[BANKER] - bets[PLAYER] - bets[TIE]);
			conn->msgAdd(balance);
			conn->msgEnd();

			result = true;
		}

		delete shue;
	}

	return result;
}

int32
BratGame::calcPayouts(int32 outcome, int32* bets, int32* payout, int32* commission, TiePayoutOdds tpo)
{
	int32 winnings = 0;

	//
	// payouts are calc'd as follows:
	//		> 0		winning bet (amt won, does *NOT* include orig bet)
	//		  0		push bet
	//		< 0		losing bet (amt lost)
	//

	switch (outcome)
	{
		case BANKER:
			if (bets[outcome])						// pays 1:1 - %5 commission
			{
				int32 dollars, cents;

				// 5% commission (round up to quarters)
				//
				dollars = (5 * bets[outcome]) / 100;
				cents = dollars % 100;
				dollars -= cents;

				if (cents)
				{
					if (cents > 75)
					{
						dollars += 100;
						cents = 0;
					}
					else if (cents > 50)
						cents = 75;
					else if (cents > 25)
						cents = 50;
					else
						cents = 25;
				}

				*commission = dollars + cents;

				payout[BANKER] = bets[outcome] - *commission;
			}
			else
			{
				payout[BANKER] = 0;					// lost (no bet)
				*commission = 0;
			}

			payout[PLAYER] = -bets[PLAYER];			// lost
			payout[TIE] = -bets[TIE];				// lost
			break;

		case PLAYER:
			payout[outcome] = bets[outcome];		// pays 1:1
			payout[BANKER] = -bets[BANKER];			// lost
			payout[TIE] = -bets[TIE];				// lost

			// no bank commission
			//
			*commission = 0;
			break;

		case TIE:
			if(tpo == NINE_TO_ONE)
			{
				payout[outcome] = 9 * bets[outcome];	// pays 9:1
			}
			else if(tpo == EIGHT_TO_ONE)
			{
				payout[outcome] = 8 * bets[outcome];	// pays 8:1
			}
			else
			{
				ASSERT(0);
				payout[outcome] = 9 * bets[outcome];
			}

			payout[BANKER] = 0;						// push
			payout[PLAYER] = 0;						// push

			// return original bets
			//
			winnings += bets[BANKER];
			winnings += bets[PLAYER];

			// no bank commission
			//
			*commission = 0;
			break;
	}

	winnings += bets[outcome] + payout[outcome];  	// orig bet + winnings

	return winnings;
}
